import { Request, Response } from 'express';
import { OSSService, UploadFileOptions, PresignedUrlOptions } from '../services/OSSService';
import { createError } from '../middleware/errorHandler';

export class OSSController {
  private ossService: OSSService;

  constructor() {
    this.ossService = new OSSService();
  }

  /**
   * 上传单个文件
   */
  uploadFile = async (req: Request, res: Response): Promise<void> => {
    try {
      if (!req.file) {
        throw createError('没有上传文件', 400);
      }

      const options: UploadFileOptions = {
        folder: req.body.folder || 'uploads',
        filename: req.body.filename,
        acl: req.body.acl || 'public-read',
        contentType: req.body.contentType || req.file.mimetype
      };

      const fileInfo = await this.ossService.uploadFile(req.file, options);

      res.status(200).json({
        success: true,
        message: '文件上传成功',
        data: fileInfo
      });
    } catch (error: any) {
      console.error('上传文件失败:', error);
      res.status(error.statusCode || 500).json({
        success: false,
        message: error.message || '文件上传失败'
      });
    }
  };

  /**
   * 批量上传文件
   */
  uploadFiles = async (req: Request, res: Response): Promise<void> => {
    try {
      const files = req.files as Express.Multer.File[];
      
      if (!files || files.length === 0) {
        throw createError('没有上传文件', 400);
      }

      const options: UploadFileOptions = {
        folder: req.body.folder || 'uploads',
        acl: req.body.acl || 'public-read'
      };

      const filesInfo = await this.ossService.uploadFiles(files, options);

      res.status(200).json({
        success: true,
        message: `成功上传 ${filesInfo.length} 个文件`,
        data: filesInfo
      });
    } catch (error: any) {
      console.error('批量上传文件失败:', error);
      res.status(error.statusCode || 500).json({
        success: false,
        message: error.message || '批量上传文件失败'
      });
    }
  };

  /**
   * 下载文件
   */
  downloadFile = async (req: Request, res: Response): Promise<void> => {
    try {
      const { key } = req.params;
      
      if (!key) {
        throw createError('文件key不能为空', 400);
      }

      const buffer = await this.ossService.downloadFile(key);
      const fileInfo = await this.ossService.getFileInfo(key);

      res.set({
        'Content-Type': fileInfo.contentType,
        'Content-Length': fileInfo.size.toString(),
        'Content-Disposition': `attachment; filename="${key.split('/').pop()}"`
      });

      res.send(buffer);
    } catch (error: any) {
      console.error('下载文件失败:', error);
      res.status(error.statusCode || 500).json({
        success: false,
        message: error.message || '文件下载失败'
      });
    }
  };

  /**
   * 获取文件信息
   */
  getFileInfo = async (req: Request, res: Response): Promise<void> => {
    try {
      const { key } = req.params;
      
      if (!key) {
        throw createError('文件key不能为空', 400);
      }

      const fileInfo = await this.ossService.getFileInfo(key);

      res.status(200).json({
        success: true,
        message: '获取文件信息成功',
        data: fileInfo
      });
    } catch (error: any) {
      console.error('获取文件信息失败:', error);
      res.status(error.statusCode || 500).json({
        success: false,
        message: error.message || '获取文件信息失败'
      });
    }
  };

  /**
   * 删除单个文件
   */
  deleteFile = async (req: Request, res: Response): Promise<void> => {
    try {
      const { key } = req.params;
      
      if (!key) {
        throw createError('文件key不能为空', 400);
      }

      await this.ossService.deleteFile(key);

      res.status(200).json({
        success: true,
        message: '文件删除成功'
      });
    } catch (error: any) {
      console.error('删除文件失败:', error);
      res.status(error.statusCode || 500).json({
        success: false,
        message: error.message || '文件删除失败'
      });
    }
  };

  /**
   * 批量删除文件
   */
  deleteFiles = async (req: Request, res: Response): Promise<void> => {
    try {
      const { keys } = req.body;
      
      if (!keys || !Array.isArray(keys) || keys.length === 0) {
        throw createError('文件keys数组不能为空', 400);
      }

      const result = await this.ossService.deleteFiles(keys);

      res.status(200).json({
        success: true,
        message: `成功删除 ${result.deleted.length} 个文件，失败 ${result.failed.length} 个`,
        data: result
      });
    } catch (error: any) {
      console.error('批量删除文件失败:', error);
      res.status(error.statusCode || 500).json({
        success: false,
        message: error.message || '批量删除文件失败'
      });
    }
  };

  /**
   * 列出文件
   */
  listFiles = async (req: Request, res: Response): Promise<void> => {
    try {
      const {
        prefix,
        maxKeys = 100,
        continuationToken
      } = req.query;

      const result = await this.ossService.listFiles(
        prefix as string,
        parseInt(maxKeys as string) || 100,
        continuationToken as string
      );

      res.status(200).json({
        success: true,
        message: '获取文件列表成功',
        data: result
      });
    } catch (error: any) {
      console.error('获取文件列表失败:', error);
      res.status(error.statusCode || 500).json({
        success: false,
        message: error.message || '获取文件列表失败'
      });
    }
  };

  /**
   * 生成预签名URL
   */
  generatePresignedUrl = async (req: Request, res: Response): Promise<void> => {
    try {
      const { key } = req.params;
      const {
        expires = 3600,
        method = 'GET',
        contentType,
        process
      } = req.query;
      
      if (!key) {
        throw createError('文件key不能为空', 400);
      }

      const options: PresignedUrlOptions = {
        expires: parseInt(expires as string),
        method: method as 'GET' | 'PUT' | 'POST' | 'DELETE',
        contentType: contentType as string,
        process: process as string
      };

      const url = await this.ossService.generatePresignedUrl(key, options);

      res.status(200).json({
        success: true,
        message: '生成预签名URL成功',
        data: { url, expires: options.expires }
      });
    } catch (error: any) {
      console.error('生成预签名URL失败:', error);
      res.status(error.statusCode || 500).json({
        success: false,
        message: error.message || '生成预签名URL失败'
      });
    }
  };

  /**
   * 复制文件
   */
  copyFile = async (req: Request, res: Response): Promise<void> => {
    try {
      const { sourceKey, targetKey } = req.body;
      
      if (!sourceKey || !targetKey) {
        throw createError('源文件key和目标文件key不能为空', 400);
      }

      await this.ossService.copyFile(sourceKey, targetKey);

      res.status(200).json({
        success: true,
        message: '文件复制成功'
      });
    } catch (error: any) {
      console.error('复制文件失败:', error);
      res.status(error.statusCode || 500).json({
        success: false,
        message: error.message || '文件复制失败'
      });
    }
  };

  /**
   * 检查文件是否存在
   */
  fileExists = async (req: Request, res: Response): Promise<void> => {
    try {
      const { key } = req.params;
      
      if (!key) {
        throw createError('文件key不能为空', 400);
      }

      const exists = await this.ossService.fileExists(key);

      res.status(200).json({
        success: true,
        message: '检查文件是否存在成功',
        data: { exists }
      });
    } catch (error: any) {
      console.error('检查文件是否存在失败:', error);
      res.status(error.statusCode || 500).json({
        success: false,
        message: error.message || '检查文件是否存在失败'
      });
    }
  };
}

export default new OSSController(); 